package cn.chiship.bs.api.biz.controller;

import cn.chiship.sdk.core.annotation.Authorization;
import cn.chiship.sdk.core.annotation.NoParamsSign;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.enums.BaseResultEnum;
import cn.chiship.sdk.core.exception.custom.BusinessException;
import cn.chiship.sdk.core.id.SnowflakeIdUtil;
import cn.chiship.sdk.core.util.DateUtils;
import cn.chiship.sdk.core.util.OutUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.bs.api.biz.pojo.vo.PageVo;
import cn.chiship.bs.api.biz.service.BaseService;
import cn.chiship.bs.api.core.util.ServletUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * @author lijian
 */
public abstract class BaseController<Record, Example> {
    /**
     * 获取业务服务
     */
    public abstract BaseService<Record, Example> getService();

    @Authorization
    @GetMapping(value = "validateExistByField")
    public ResponseEntity<BaseResult> validateExistByField(
            @RequestParam(required = false, defaultValue = "", value = "id") String id,
            @RequestParam(value = "field") String field,
            @RequestParam(value = "value") String value) {
        return new ResponseEntity<>(getService().validateExistByField(id, field, value), HttpStatus.OK);
    }

    @PostMapping(value = "exportData")
    public void exportData(@RequestBody JSONObject paramsMap, HttpServletResponse response) throws Exception {
        String a = "exportType";
        if (!paramsMap.containsKey(a)) {
            throw new BusinessException("缺少参数[" + a + "]");
        }
        String exportType = paramsMap.get(a).toString();
        if (StringUtil.isNullOrEmpty(exportType)) {
            BaseResult baseResult = BaseResult.error("参数[" + a + "]不能为空");
            OutUtil.writeJson(response, baseResult);
        }
        boolean async = false;
        String b = "async";
        if (paramsMap.containsKey(b)) {
            async = paramsMap.getBoolean(b);
        }
        if (async) {
            String taskId = DateUtils.dateTimeNow() + SnowflakeIdUtil.generateId();
            getService().asyncExportData(response, taskId, paramsMap);
            OutUtil.writeJson(response, BaseResult.ok(taskId));
        } else {
            getService().exportData(response, paramsMap);
        }
    }

    @PostMapping(value = "getExportProcessStatus")
    public void getExportProcessStatus(HttpServletResponse response, @RequestBody Map<String, Object> paramsMap) throws Exception {
        String taskId = paramsMap.get("taskId").toString();
        if (StringUtil.isNullOrEmpty(taskId)) {
            BaseResult baseResult = BaseResult.error(BaseResultEnum.FAILED, "缺少参数[taskId]");
            OutUtil.writeJson(response, baseResult);
        }
        getService().getExportProcessStatus(response, taskId);
    }

    @PostMapping(value = "/importData")
    @NoParamsSign
    public ResponseEntity<BaseResult> importData(@RequestParam("file") MultipartFile multipartFile) throws Exception {
        if (multipartFile.isEmpty()) {
            return new ResponseEntity<>(BaseResult.error("上传失败，请选择文件"), HttpStatus.OK);
        }
        Map<String, Object> paramMap = ServletUtil.getParameterValues();
        paramMap.put("fileName", multipartFile.getOriginalFilename());
        paramMap.put("contentType", multipartFile.getContentType());
        InputStream is = multipartFile.getInputStream();
        String taskId = DateUtils.dateTimeNow() + SnowflakeIdUtil.generateId();
        getService().asyncImportData(is, taskId, paramMap);
        return new ResponseEntity<>(BaseResult.ok(taskId), HttpStatus.OK);

    }

    @PostMapping("/getImportProcessStatus")
    @NoParamsSign
    public ResponseEntity getImportProcessStatus(@RequestBody Map<String, Object> paramsMap) {
        String taskId = paramsMap.get("taskId").toString();
        if (StringUtil.isNullOrEmpty(taskId)) {
            return new ResponseEntity<>(BaseResult.error("缺少参数[taskId]"), HttpStatus.OK);
        }
        return new ResponseEntity<>(getService().getImportProcessStatus(taskId), HttpStatus.OK);
    }

    @GetMapping(value = "getById/{id}")
    public ResponseEntity<BaseResult> getById(@PathVariable("id") String id) {
        return new ResponseEntity<>(BaseResult.ok(getService().selectByPrimaryKey(id)), HttpStatus.OK);
    }

    @GetMapping(value = "getDetailsById/{id}")
    public ResponseEntity<BaseResult> getDetailsById(@PathVariable("id") String id) {
        return new ResponseEntity<>(getService().selectDetailsByPrimaryKey(id), HttpStatus.OK);
    }


    /**
     * 分页
     *
     * @param example 条件
     */
    public PageVo page(Example example) {
        PageVo pageVo = new PageVo();

        Integer pageIndex;
        Integer pageSize;
        String sort = "-gmt_modified";
        try {
            pageIndex = (ServletUtil.getParameterToInt(BaseConstants.PAGE_NUM));
            pageSize = (ServletUtil.getParameterToInt(BaseConstants.PAGE_SIZE));
            sort = (ServletUtil.getParameter(BaseConstants.PAGE_SORT));
            if (pageIndex == null) {
                pageIndex = 1;
            }
            if (pageSize == null) {
                pageSize = 20;
            }
        } catch (Exception e) {
            pageIndex = 1;
            pageSize = 20;
        }
        pageVo.setCurrent(pageIndex.longValue());
        pageVo.setSize(pageSize.longValue());
        return getService().selectPageByExample(pageVo, example, sort);
    }

    /**
     * 列表
     *
     * @param example 条件
     * @return 结果
     */
    public List<Record> list(Example example) {
        return getService().selectByExample(example);
    }

    /**
     * 新增
     *
     * @param record 实体类
     * @return 结果
     */
    public BaseResult save(Record record) {
        return getService().insertSelective(record);
    }

    /**
     * 修改
     *
     * @param record 实体
     * @return 结果
     */
    public BaseResult update(Object id, Record record) {
        Class<?> clazz = record.getClass();
        try {
            if (StringUtil.isNull(id)) {
                return BaseResult.error(BaseResultEnum.BUSINESS_ERROR, "参数[id]不能为空");
            }
            Field idField = clazz.getDeclaredField("id");
            idField.setAccessible(true);
            idField.set(record, id);
            return getService().updateByPrimaryKeySelective(record);
        } catch (Exception e) {
            throw new BusinessException(e.getLocalizedMessage());
        }
    }

    /**
     * 删除
     *
     * @param example 条件
     */
    public BaseResult remove(Example example) {
        return getService().deleteByExample(example);
    }

    protected ResponseEntity<BaseResult> responseEntity(BaseResult baseResult) {
        return responseEntity(baseResult, HttpStatus.OK);
    }

    protected ResponseEntity<BaseResult> responseEntity(BaseResult baseResult, HttpStatus httpStatus) {
        return new ResponseEntity<>(baseResult, httpStatus);
    }
}
